package org.platform.core.filecommand;

import com.mc.mic.core.tool.helper.SpringContextHelper;
import it.sauronsoftware.ftp4j.FTPFile;
import lombok.AllArgsConstructor;
import lombok.NoArgsConstructor;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang3.StringUtils;
import org.platform.core.JobManager;
import org.platform.tool.util.FtpClientUtil;
import org.quartz.JobKey;
import org.quartz.SimpleScheduleBuilder;
import org.quartz.SimpleTrigger;
import org.quartz.TriggerBuilder;
import org.quartz.impl.JobDetailImpl;

import java.io.File;
import java.util.List;

/**
 * FTP监视类
 *
 * @author wangwwenj
 * @date 2017/2/1
 */
@NoArgsConstructor
@AllArgsConstructor
public class FtpWatchJob {
    /**
     * IP地址
     */
    private String host;
    /**
     * 端口
     */
    private int port;
    /**
     * 用户名
     */
    private String username;
    /**
     * 密码
     */
    private String password;
    /**
     * 监视目录
     */
    private String[] remoteDirNames;
    /**
     * 备份目录
     */
    private String[] backDirNames;
    /**
     * 下载文件存储目录
     */
    private String indexDirName;
    /**
     * 后缀名
     */
    private String[] suffixNames;

    private boolean flag = false;

    /**
     * 构造方法
     *
     * @param host          IP地址
     * @param port          端口
     * @param username      用户名 (用户名为空表示匿名登录)
     * @param password      密码
     * @param remoteDirName 监视目录{为数组，可以配置多个监视目录}
     * @param backDirName   备份目录{为数组，可以配置多个备份目录，数量和监视目录一致}
     * @param indexDirName  下载文件存储目录
     * @param suffixName    须下载文件后缀名{为数组，可以同时配置多个后缀名判断，如果不需要判断后缀传入null}
     */
    public FtpWatchJob(String host, int port, String username, String password, String[] remoteDirName, String[] backDirName, String indexDirName, String[] suffixName) {
        this.host = host;
        this.port = port;
        this.username = username;
        this.password = password;
        this.remoteDirNames = remoteDirName;
        this.backDirNames = backDirName;
        this.indexDirName = indexDirName;
        this.suffixNames = suffixName;
    }


    /**
     * 定时开启FTP扫描ftp目录下文件是否存在，存在就下载并备份
     */
    private void watch() {
        FtpClientUtil ftp = FtpClientUtil.getInstance(host, username, password);
        for (int number = 0; number < remoteDirNames.length; number++) {
            try {
                //得到其中一个监视目录
                String remoteDirName = remoteDirNames[number];
                //得到其中一个备份目录
                String backDirName = backDirNames[number];
                List<FTPFile> ftpFiles = ftp.listFiles(remoteDirName);
                if (ftpFiles != null && !ftpFiles.isEmpty()) {

                    for (FTPFile ftpFile : ftpFiles) {
                        //获取后缀名
                        String suffix = ftpFile.getName().substring(ftpFile.getName().lastIndexOf('.'), ftpFile.getName().length());
                        //判断是否需要下载
                        if (suffixNames == null || ArrayUtils.contains(suffixNames, suffix)) {
                            //得到无后缀名的文件名
                            String fileName = ftpFile.getName();
                            if (fileName.indexOf(".") > 0) {
                                fileName = fileName.substring(0, fileName.indexOf("."));
                            }
                            ftp.downloadFile(remoteDirName + ftpFile.getName(), indexDirName, fileName);
                            //将ftp上文件移到备份目录
                            boolean renameFile = ftp.renameFile(remoteDirName + ftpFile.getName(), backDirName + ftpFile.getName());
                            if (renameFile) {
                                //执行监听流程:
                                String fileTxt = FileUtils.readFileToString(new File(indexDirName + "/" + fileName + suffix));
                                JobDetailImpl jd = new JobDetailImpl();
                                jd.getJobDataMap().put("FilePath", fileName);
                                jd.getJobDataMap().put("FileName", fileName);
                                jd.getJobDataMap().put("txtMsg", fileTxt);
                                jd.setJobClass(BaseFileCommandJob.class);
                                String cmdDesc = StringUtils.join("file_Task", fileName);
                                jd.setKey(JobKey.jobKey(cmdDesc));
                                SimpleTrigger trigger = TriggerBuilder.newTrigger().withSchedule(SimpleScheduleBuilder.simpleSchedule().withRepeatCount(0)).startNow().build();
                                SpringContextHelper.getBean(JobManager.class).register(jd, trigger);
                            }
                        }
                    }
                }
                //其中一个监视完成后将FTP目录地址重置为根目录
                ftp.rootChangeDirectory();
                Thread.sleep(200);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        ftp.disconnect();
    }

    /**
     * 启动定时扫描
     */
    public void start() {
        flag = true;
        new Thread(() -> {
            System.out.println("FTP监视线程开启");
            while (true) {
                try {
                    if (flag) {
                        this.watch();
                    } else {
                        break;
                    }
                    Thread.sleep(3000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();
    }

    /**
     * 停止定时扫描
     */
    public void stop() {
        flag = false;
        System.out.println("FTP监视线程关闭！");
    }

}
